Aux Resources

Aux Resources

<<<<<<< HEAD

Notes I Wish I Had When I Started Learning Python

Plus resources for learning data structures and algorithms in python at the bottom of this article!

Bryan GunerBryan GunerAug 24·22 min read

Basics

  • PEP8 : Python Enhancement Proposals, style-guide for Python.

  • print is the equivalent of console.log.

  • # is used to make comments in your code.

def foo():
"""
The foo function does many amazing things that you
should not question. Just accept that it exists and
use it with caution.
"""
secretThing()
  • Python has a built in help function that let’s you see a description of the source code without having to navigate to it.

Numbers

  • Python has three types of numbers:

  • Integer

  • Positive and Negative Counting Numbers.

  • No Decimal Point

  • Created by a literal non-decimal pt number or with the int() constructor.

print(3) # => 3 print(int(19)) # => 19 print(int()) # => 0
  • Boolean is a subtype of integer in Python.

  • Floating Point Number

  • Decimal Numbers.

print(2.24) # => 2.24 print(2.) # => 2.0 print(float()) # => 0.0 print(27e-5) # => 0.00027

Complex Numbers

  • Consist of a real part and imaginary part.

  • The i is switched to a j in programming.

print(7j) # => 7j print(5.1+7.7j)) # => 5.1+7.7j print(complex(3, 5)) # => 3+5j print(complex(17)) # => 17+0j print(complex()) # => 0j

Type Casting : The process of converting one number to another.

# Using Float
print(17) # => 17
print(float(17)) # => 17.0# Using Int
print(17.0) # => 17.0
print(int(17.0)) # => 17# Using Str
print(str(17.0) + ' and ' + str(17)) # => 17.0 and 17
  • The arithmetic operators are the same between JS and Python, with two additions:

  • “**” : Double asterisk for exponent.

  • “//” : Integer Division.

  • There are no spaces between math operations in Python.

  • Integer Division gives the other part of the number from Module; it is a way to do round down numbers replacing Math.floor() in JS.

  • There are no ++ and -- in Python, the only shorthand operators are:

Strings

  • Python uses both single and double quotes.

  • You can escape strings like so 'Jodi asked, "What\'s up, Sam?"'

  • Multiline strings use triple quotes.

print('''My instructions are very long so to make them
more readable in the code I am putting them on
more than one line. I can even include "quotes"
of any kind because they won't get confused with
the end of the string!''')
  • Use the len() function to get the length of a string.

print(len("Spaghetti")) # => 9
  • Python uses zero-based indexing

  • Python allows negative indexing (thank god!)

print("Spaghetti"[-1]) # => i print("Spaghetti"[-4]) # => e
  • Python let’s you use ranges

print("Spaghetti"[1:4]) # => pag print("Spaghetti"[4:-1]) # => hett print("Spaghetti"[4:4]) # => (empty string)
  • The end range is exclusive just like slice in JS.

# Shortcut to get from the beginning of a string to a certain index.
print("Spaghetti"[:4]) # => Spag
print("Spaghetti"[:-1]) # => Spaghett# Shortcut to get from a certain index to the end of a string.
print("Spaghetti"[1:]) # => paghetti
print("Spaghetti"[-4:]) # => etti
  • The index string function is the equiv. of indexOf() in JS

print("Spaghetti".index("h")) # => 4
print("Spaghetti".index("t")) # => 6
  • The count function finds out how many times a substring appears in a string.

print("Spaghetti".count("h")) # => 1
print("Spaghetti".count("t")) # => 2
print("Spaghetti".count("s")) # => 0
print('''We choose to go to the moon in this decade and do the other things,
not because they are easy, but because they are hard, because that goal will
serve to organize and measure the best of our energies and skills, because that
challenge is one that we are willing to accept, one we are unwilling to
postpone, and one which we intend to win, and the others, too.
'''.count('the ')) # => 4
  • You can use + to concatenate strings, just like in JS.

  • You can also use “*” to repeat strings or multiply strings.

  • Use the format() function to use placeholders in a string to input values later on.

first_name = "Billy"
last_name = "Bob"
print('Your name is {0} {1}'.format(first_name, last_name)) # => Your name is Billy Bob
  • Shorthand way to use format function is: print(f'Your name is {first_name} {last_name}')

  • Some useful string methods.

  • Note that in JS join is used on an Array, in Python it is used on String.

  • There are also many handy testing methods.

Variables and Expressions

  • Duck-Typing : Programming Style which avoids checking an object’s type to figure out what it can do.

  • Duck Typing is the fundamental approach of Python.

  • Assignment of a value automatically declares.

a = 7
b = 'Marbles'
print(a) # => 7
print(b) # => Marbles
  • You can chain variable assignments to give multiple var names the same value.

  • Use with caution as this is highly unreadable

count = max = min = 0
print(count) # => 0
print(max) # => 0
print(min) # => 0
  • The value and type of a variable can be re-assigned at any time.

a = 17
print(a) # => 17
a = 'seventeen'
print(a) # => seventeen
  • NaN does not exist in Python, but you can 'create' it like so: print(float("nan"))

  • Python replaces null with none.

  • none is an object and can be directly assigned to a variable.

  • Using none is a convenient way to check to see why an action may not be operating correctly in your program.

Boolean Data Type

  • One of the biggest benefits of Python is that it reads more like English than JS does.

# Logical AND
print(True and True) # => True
print(True and False) # => False
print(False and False) # => False# Logical OR
print(True or True) # => True
print(True or False) # => True
print(False or False) # => False# Logical NOT
print(not True) # => False
print(not False and True) # => True
print(not True or False) # => False
  • By default, Python considers an object to be true UNLESS it is one of the following:

  • Constant None or False

  • Zero of any numeric type.

  • Empty Sequence or Collection.

  • True and False must be capitalized

Comparison Operators

  • Python uses all the same equality operators as JS.

  • In Python, equality operators are processed from left to right.

  • Logical operators are processed in this order:

  • NOT

  • AND

  • OR

  • Just like in JS, you can use parentheses to change the inherent order of operations.

  • Short Circuit : Stopping a program when a true or false has been reached.

Identity vs Equality

print (2 == '2') # => False
print (2 is '2') # => Falseprint ("2" == '2') # => True
print ("2" is '2') # => True# There is a distinction between the number types.
print (2 == 2.0) # => True
print (2 is 2.0) # => False
  • In the Python community it is better to use is and is not over == or !=

If Statements

if name == 'Monica':
print('Hi, Monica.')if name == 'Monica':
print('Hi, Monica.')
else:
print('Hello, stranger.')if name == 'Monica':
print('Hi, Monica.')
elif age < 12:
print('You are not Monica, kiddo.')
elif age > 2000:
print('Unlike you, Monica is not an undead, immortal vampire.')
elif age > 100:
print('You are not Monica, grannie.')
  • Remember the order of elif statements matter.

While Statements

spam = 0
while spam < 5:
print('Hello, world.')
spam = spam + 1
  • Break statement also exists in Python.

spam = 0
while True:
print('Hello, world.')
spam = spam + 1
if spam >= 5:
break
  • As are continue statements

spam = 0
while True:
print('Hello, world.')
spam = spam + 1
if spam < 5:
continue
break

Try/Except Statements

  • Python equivalent to try/catch

a = 321
try:
print(len(a))
except:
print('Silently handle error here') # Optionally include a correction to the issue
a = str(a)
print(len(a)a = '321'
try:
print(len(a))
except:
print('Silently handle error here') # Optionally include a correction to the issue
a = str(a)
print(len(a))
  • You can name an error to give the output more specificity.

a = 100
b = 0
try:
c = a / b
except ZeroDivisionError:
c = None
print(c)
  • You can also use the pass commmand to by pass a certain error.

a = 100
b = 0
try:
print(a / b)
except ZeroDivisionError:
pass
  • The pass method won't allow you to bypass every single error so you can chain an exception series like so:

a = 100
# b = "5"
try:
print(a / b)
except ZeroDivisionError:
pass
except (TypeError, NameError):
print("ERROR!")
  • You can use an else statement to end a chain of except statements.

# tuple of file names
files = ('one.txt', 'two.txt', 'three.txt')# simple loop
for filename in files:
try:
# open the file in read mode
f = open(filename, 'r')
except OSError:
# handle the case where file does not exist or permission is denied
print('cannot open file', filename)
else:
# do stuff with the file object (f)
print(filename, 'opened successfully')
print('found', len(f.readlines()), 'lines')
f.close()
  • finally is used at the end to clean up all actions under any circumstance.

def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("Cannot divide by zero")
else:
print("Result is", result)
finally:
print("Finally...")
  • Using duck typing to check to see if some value is able to use a certain method.

# Try a number - nothing will print out
a = 321
if hasattr(a, '__len__'):
print(len(a))# Try a string - the length will print out (4 in this case)
b = "5555"
if hasattr(b, '__len__'):
print(len(b))

Pass

  • Pass Keyword is required to write the JS equivalent of :

if (true) {
}while (true) {}if True:
passwhile True:
pass

Functions

  • Function definition includes:

  • The def keyword

  • The name of the function

  • A list of parameters enclosed in parentheses.

  • A colon at the end of the line.

  • One tab indentation for the code to run.

def printCopyright():
print("Copyright 2020. Me, myself and I. All rights reserved.")
  • You can use default parameters just like in JS

def greeting(name, saying="Hello"):
print(saying, name)greeting("Monica")
# Hello Monicagreeting("Barry", "Hey")
# Hey Barry
  • Keep in mind, default parameters must always come after regular parameters.

# THIS IS BAD CODE AND WILL NOT RUN
def increment(delta=1, value):
return delta + value
  • You can specify arguments by name without destructuring in Python.

def greeting(name, saying="Hello"):
print(saying, name)# name has no default value, so just provide the value
# saying has a default value, so use a keyword argument
greeting("Monica", saying="Hi")
  • The lambda keyword is used to create anonymous functions and are supposed to be one-liners.

toUpper = lambda s: s.upper()

Notes

Formatted Strings

  • Remember that in Python join() is called on a string with an array/list passed in as the argument.

shopping_list = ['bread','milk','eggs']
print(','.join(shopping_list))
  • Python has a very powerful formatting engine.

  • format() is also applied directly to strings.

# Comma Thousands Separator
print('{:,}'.format(1234567890))
'1,234,567,890'# Date and Time
d = datetime.datetime(2020, 7, 4, 12, 15, 58)
print('{:%Y-%m-%d %H:%M:%S}'.format(d))
'2020-07-04 12:15:58'# Percentage
points = 190
total = 220
print('Correct answers: {:.2%}'.format(points/total))
Correct answers: 86.36%# Data Tables
width=8
print(' decimal hex binary')
print('-'*27)
for num in range(1,16):
for base in 'dXb':
print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ')
print()

Getting Input from the Command Line

  • Python runs synchronously, all programs and processes will stop when listening for a user input.

  • The input function shows a prompt to a user and waits for them to type 'ENTER'.

Scripts vs Programs

  • Programming Script : A set of code that runs in a linear fashion.

  • The largest difference between scripts and programs is the level of complexity and purpose. Programs typically have many UI’s.

  • Python can be used to display html, css, and JS.

  • We will be using Python as an API (Application Programming Interface)

Structured Data

  • Sequence : The most basic data structure in Python where the index determines the order.

  • List

  • Tuple

  • Range

Collections : Unordered data structures, hashable values.

  • Dictionaries

  • Sets

  • Iterable : Generic name for a sequence or collection; any object that can be iterated through.

  • Can be mutable or immutable.

Built In Data Types

  • Lists are the python equivalent of arrays.

empty_list = []
departments = ['HR','Development','Sales','Finance','IT','Customer Support']# You can instantiate
specials = list()# Test if a value is in a list.
print(1 in [1, 2, 3]) #> True
print(4 in [1, 2, 3]) #> False
  • Tuples : Very similar to lists, but they are immutable

# Instantiated with parentheses
time_blocks = ('AM','PM')# Sometimes instantiated without
colors = 'red','blue','green'
numbers = 1, 2, 3# Tuple() built in can be used to convert other data into a tuple
tuple('abc') # returns ('a', 'b', 'c')
tuple([1,2,3]) # returns (1, 2, 3)
  • Think of tuples as constant variables.

  • Ranges : A list of numbers which can’t be changed; often used with for loops.

  • Declared using one to three parameters.

  • Start : opt. default 0, first # in sequence.

  • Stop : required next number past the last number in the sequence.

  • Step : opt. default 1, difference between each number in the sequence.

range(5) # [0, 1, 2, 3, 4]
range(1,5) # [1, 2, 3, 4]
range(0, 25, 5) # [0, 5, 10, 15, 20]
range(0) # [ ]for let (i = 0; i < 5; i++)
for let (i = 1; i < 5; i++)
for let (i = 0; i < 25; i+=5)
for let(i = 0; i = 0; i++)
  • Keep in mind that stop is not included in the range.

  • Dictionaries : Mappable collection where a hashable value is used as a key to ref. an object stored in the dictionary.

  • Mutable.

a = {'one':1, 'two':2, 'three':3}
b = dict(one=1, two=2, three=3)
c = dict([('two', 2), ('one', 1), ('three', 3)])

a, b, and c are all equal

  • Declared with curly braces of the built in dict()

  • Benefit of dictionaries in Python is that it doesn’t matter how it is defined, if the keys and values are the same the dictionaries are considered equal.

  • Use the in operator to see if a key exists in a dictionary.

Sets : Unordered collection of distinct objects; objects that need to be hashable.

  • Always be unique, duplicate items are auto dropped from the set.

  • Common Uses:

  • Removing Duplicates

  • Membership Testing

  • Mathematical Operators: Intersection, Union, Difference, Symmetric Difference.

  • Standard Set is mutable, Python has a immutable version called frozenset.

  • Sets created by putting comma seperated values inside braces:

school_bag = {'book','paper','pencil','pencil','book','book','book','eraser'}
print(school_bag)# Also can use set constructor to automatically put it into a set.
letters = set('abracadabra')
print(letters)

Built-In Functions

Functions using iterables

  • filter(function, iterable) : creates new iterable of the same type which includes each item for which the function returns true.

  • map(function, iterable) : creates new iterable of the same type which includes the result of calling the function on every item of the iterable.

  • sorted(iterable, key=None, reverse=False) : creates a new sorted list from the items in the iterable.

  • Output is always a list

  • key: opt function which coverts and item to a value to be compared.

  • reverse: optional boolean.

  • enumerate(iterable, start=0) : starts with a sequence and converts it to a series of tuples

quarters = ['First', 'Second', 'Third', 'Fourth']
print(enumerate(quarters))
print(enumerate(quarters, start=1))# (0, 'First'), (1, 'Second'), (2, 'Third'), (3, 'Fourth')
# (1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth')
  • zip(*iterables) : creates a zip object filled with tuples that combine 1 to 1 the items in each provided iterable.

Functions that analyze iterables

  • len(iterable) : returns the count of the number of items.

  • max(*args, key=None) : returns the largest of two or more arguments.

  • max(iterable, key=None) : returns the largest item in the iterable.

  • key optional function which converts an item to a value to be compared.

  • min works the same way as max

  • sum(iterable) : used with a list of numbers to generate the total.

  • There is a faster way to concatenate an array of strings into one string, so do not use sum for that.

  • any(iterable) : returns True if any items in the iterable are true.

  • all(iterable) : returns True is all items in the iterable are true.

Working with dictionaries

  • dir(dictionary) : returns the list of keys in the dictionary.

Working with sets

  • Union : The pipe | operator or union(*sets) function can be used to produce a new set which is a combination of all elements in the provided set.

a = {1, 2, 3}
b = {2, 4, 6}
print(a | b) # => {1, 2, 3, 4, 6}
  • Intersection : The & operator ca be used to produce a new set of only the elements that appear in all sets.

a = {1, 2, 3}
b = {2, 4, 6}
print(a & b) # => {2}
  • Difference : The — operator can be used to produce a new set of only the elements that appear in the first set and NOT the others.

  • Symmetric Difference : The ^ operator can be used to produce a new set of only the elements that appear in exactly one set and not in both.

a = {1, 2, 3}
b = {2, 4, 6}
print(a - b) # => {1, 3}
print(b - a) # => {4, 6}
print(a ^ b) # => {1, 3, 4, 6}

For Statements

  • In python, there is only one for loop.

  • Always Includes:

  • The for keyword

  • A variable name

  • The in keyword

  • An iterable of some kid

  • A colon

  • On the next line, an indented block of code called the for clause.

  • You can use break and continue statements inside for loops as well.

  • You can use the range function as the iterable for the for loop.

print('My name is')
for i in range(5):
print('Carlita Cinco (' + str(i) + ')')total = 0
for num in range(101):
total += num
print(total)
  • Looping over a list in Python

for c in ['a', 'b', 'c']:
print(c)lst = [0, 1, 2, 3]
for i in lst:
print(i)
  • Common technique is to use the len() on a pre-defined list with a for loop to iterate over the indices of the list.

supplies = ['pens', 'staplers', 'flame-throwers', 'binders']
for i in range(len(supplies)):
print('Index ' + str(i) + ' in supplies is: ' + supplies[i])
  • You can loop and destructure at the same time.

l = [[1, 2], [3, 4], [5, 6]]
for a, b in l:
print(a, ', ', b)# Prints 1, 2
# Prints 3, 4
# Prints 5, 6
  • You can use values() and keys() to loop over dictionaries.

spam = {'color': 'red', 'age': 42}
for v in spam.values():
print(v)# Prints red
# Prints 42for k in spam.keys():
print(k)# Prints color
# Prints age
  • For loops can also iterate over both keys and values.

# Getting tuples
for i in spam.items():
print(i)# Prints ('color', 'red')
# Prints ('age', 42)
# Destructuring to values
for k, v in spam.items():
print('Key: ' + k + ' Value: ' + str(v))# Prints Key: age Value: 42
# Prints Key: color Value: red
  • Looping over string

for c in "abcdefg":
print(c)

More On Functions

  • Variable-length positional arguments : (*args)

def add(a, b, *args):
total = a + b;
for n in args:
total += n
return totaladd(1, 2) # Returns 3add(2, 3, 4, 5) # Returns 14
  • keyword arguments : (*kwargs)

def print_names_and_countries(greeting, **kwargs):
for k, v in kwargs.items():
print(greeting, k, "from", v)print_names_and_countries("Hi",
Monica="Sweden",
Charles="British Virgin Islands",
Carlo="Portugal")
# Prints
# Hi Monica from Sweden
# Hi Charles from British Virgin Islands
# Hi Carlo from Portugal
  • When you order arguments within a function or function call, the args need to occur in a particular order:

  • formal positional args.

  • *args

  • keyword args with default values

  • **kwargs

def example(arg_1, arg_2, *args, **kwargs):
passdef example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blowfish", **kwargs):
pass

Importing in Python

  • Modules are similar to packages in Node.js

  • Come in different types: Built-In, Third-Party, Custom.

  • All loaded using import statements.

Terms

  • module : Python code in a separate file.

  • package : Path to a directory that contains modules.

  • **init.py** : Default file for a package.

  • submodule : Another file in a module’s folder.

  • function : Function in a module.

  • A module can be any file but it is usually created by placing a special file __init__.py into a folder.

  • Try to avoid importing with wildcards in Python.

  • Use multiple lines for clarity when importing.

from urllib.request import (
HTTPDefaultErrorHandler as ErrorHandler,
HTTPRedirectHandler as RedirectHandler,
Request,
pathname2url,
url2pathname,
urlopen,
)

Watching Out for Python 2

  • Python 3 removed <> and only uses !=

  • format() was introduced with P3

  • All strings in P3 are unicode and encoded.

  • md5 was removed.

  • ConfigParser was renamed to configparser

  • sets were killed in favor of set() class.

  • print was a statement in P2, but is a function in P3.

Classes In Python

  • Classes are a way of combining information and behavior.

  • Classes are blueprints to make objects.

class AngryBird {
constructor() {
this.x = 0;
this.y = 0;
}
}class AngryBird:
def __init__(self):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self.x = 0
self.y = 0
  • Both JS and PY use the class keyword to declare classes.

  • constructor == __init__

  • this == self

bird = AngryBird()
print(bird.x, bird.y) #> 0 0class AngryBird:
def __init__(self):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self.x = 0
self.y = 0 def move_up_by(self, delta):
self.y += delta
  • Note how you do not need to define self it is already bound to the class.

  • It is good practice to write a comment at the beginning of your class, describing the class.

Dunder Methods

  • Double Underscore Methods, special built in functions that PY uses in certain ways.

  • i.e. __init__() lets you make sure all relevant attributes are set to their proper values when an object is created from the class.

  • The self keyword refers to the current object that you are working with.

  • Method is a function that is part of a class.

class AngryBird:
def __init__(self):
self.x = 0
self.y = 0 def move_up_by(self, delta):
self.y += delta
bird = AngryBird()
print(bird)
print(bird.y)
bird.move_up_by(5)
print(bird.y)
  • Use one leading underscore only for non-public methods and instance variables

class AngryBird:
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y def move_up_by(self, delta):
self._y += delta def get_x(self):
return self._x def get_y(self):
return self._y
  • All instance variables should be considered non-public

  • **slots** : Dunder class variable used to reserve memory for the instance variables that you know will you will use.

class AngryBird:
__slots__ = ['_x', '_y'] def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y def move_up_by(self, delta):
self._y += delta def get_x(self):
return self._x def get_y(self):
return self._y
  • You can use __repr__() to override the behavior of printing out a class in a verbose manner.

class AngryBird:
__slots__ = ['_x', '_y'] def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y def move_up_by(self, delta):
self._y += delta def get_x(self):
return self._x def get_y(self):
return self._y def __repr__(self):
return f"<AngryBird ({self._x}, {self._y})>"

Properties for Classes

  • Getters and Setters are used in object-oriented programming to add validation logic around getting and setting a value.

Getters

bird = AngryBird()print(bird.get_x(), bird.get_y())
  • Getting the x and y values of our class can get very cumbersome.

  • Decorators : Allow us to change the way methods get invoked.

  • Always start with the @ symbol.

  • Can be applied to methods, classes, and parameters.

  • Built in decorator named property that you can apply to a method to make it readable.

@property
def x(self):
return self._x @property
def y(self):
return self._y bird = AngryBird() print(bird.x, bird.y)

Setters

class AngryBird:
def __init__(self, x=0, y=0):
"""
Construct a new AngryBird by setting its position to (0, 0).
"""
self._x = x
self._y = y def move_up_by(self, delta):
self._y += delta @property
def x(self):
return self._x @x.setter
def x(self, value):
if value < 0:
value = 0
self._x = value @property
def y(self):
return self._y @y.setter
def y(self, value):
if value < 0:
value = 0
self._y = value

List Comprehensions

  • List comprehensions are the equivalent of wrapped up filter namp array methods while also allowing nested loops.

  • new_list = [expression for member in iterable]

  • expression : member itself, a call to a methd, or any other valid expression that returns a value.

  • member : object or value in the list or iterable.

  • iterable : iterable.

new_list = [expression for member in iterable (if conditional)]

  • Adding a conditional into a list comprehension.

sentence = 'Mary, Mary, quite contrary, how does your garden grow?'
def is_consonant(letter):
vowels = "aeiou"
return letter.isalpha() and letter.lower() not in vowelsconsonants = [i for i in sentence if is_consonant(i)]print(consonants)
# Prints ['M', 'r', 'y', 'M', 'r', 'y', 'q', 't', 'c',
# 'n', 't', 'r', 'r', 'y', 'h', 'w', 'd', 's', 'y',
# 'r', 'g', 'r', 'd', 'n', 'g', 'r', 'w']

When to not use list comprehensions

  • List comprehensions may make your code run more slowly or use more memory.

  • You can use nest lists to create matrices.

matrix = [[i for i in range(5)] for _ in range(6)]print(matrix)
# Prints
# [
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4],
# [0, 1, 2, 3, 4]
# ]

My Blog:

Web-Dev-HubMemoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of…master--bgoonz-blog.netlify.app

Python Data Structures & Algorithms Resources:

Algorithms:

Data Structures:

=======

e4bf9b77d4b065ed20f39ffb8a1f8425c6ab66cf

First things first, the repo with all the exercises of this lecture is right here:

https://github.com/hugoestradas/Python_Basics

Let's begin!

1) Find prime factors.

For the very basics, let's start with something unusual: Public Key Encryption. This technique relies on certain really large numbers being computationally hard to factor to keep data secure. In this first exercise I'll factor some numbers that are easy to deal with; the goal is to create a Python function to find all prime factors, I'll do it by taking an integer value as input and the return or output will be a list of prime factors.

In this solution I decided to search for factors by dividing the given sequentially larger values (starting from 2) to see which one divide evenly into it, without leaving a remainder behind:

Alt Text

As you can see I'm calling the function with the 500 number, so it will begin with 2 as the original divisor, then it'll go on keep dividing until the remainder is no longer an even number, in this case resulting in the result of 2, 2, 5, and finally 5:

Alt Text

2) Identifying Palindromes.

This a very usual programming and software engineering exercise, maybe you already did it on colleague, school or watching another tutorial, it's a very cool puzzle to solve because involves pattern recognition, logic and of course coding.

In case it's your first time dealing with palindromes, a palindrome is a word or text that reads exactly the same, either forwards or backwards.

Again, I'll write a function to detect palindromes, where my input will be the string I'm checking and the result or output is going to be a boolean value (false/true):

Alt Text

Going line by line, first I'm importing the "re" library, which contains regular expressions to extract letters from an input string, then I'm defining a "palindrome" function that receives a "string" parameter. Then I use the lower operator in the input string to convert all of the letters to lowercase, then I pass the result to the regular expression "findall" function with a pattern that will search for combinations of one or more letters. Tat will produce a list with all of the matched sub-strings that I merged together into a single string using the "join" function.

Then I slice the entire string, with the stride set to negative one, meaning I'll get a copy of the original string in reverse order.

Finally, I'm comparing both strings and return it:

Alt Text

Alt Text

3) Sort a string.

Another common task in programming is sorting things.

The goal is to create a Python function that sorts the words within a given string.

The input will be a list of words separated by spaces, and the result or output will be the same string of words sorted alphabetically:

Alt Text

My "sorted" function starts with the "split" method, which breaks apart the input string at each of the spaces and gives me a list of the individual word.

Then, to ignore the capitalization (if there is any) in the loop I convert each word within the list into lower case, to later on sort the entire list:

Alt Text

4) The waiting game.

For this exercise I'll write a Python function, which is when invoked it'll print a message to wait a random amount of time.

The user press enters, then the timer starts. The user's goal is to wait the specified number of seconds in the message, and then press enter again.

Alt Text

For this exercise I used to modules, "time" module to measure the amount of time, and the "random" module to generate a random number of seconds.

The input function prompts the user to press enter to begin and then blocks the execution until the user hits enter again.

Alt Text

5) Generate a new password.

For this final example, I'll implement a function based on the "Diceware" method, which is a method for creating passphrases and passwords using the numbers of an ordinary dice as hardware random number generator. It involves a list of over 7000 different words.

Instead of rolling a physical dice, I'll write a Python function that simulates this behavior.

The input will be a number of words in a passphrase and the output or result will be a string of random words, separated by spaces.

For this one, I could've used the "random" module, but instead I went for the "secret" module, since the random module is not recommended when dealing with cryptographic procedures:

Alt Text

My function begins by getting the number of words, then opening the "diceware.wordlist.asc" file with a context manager and then uses "readlines" function to get a list with each of the lines within the file.

The top of the file diceware that I used has two extra lines before the word list actually begins, and at the bottom there are also several extra lines for a PGP signature:

Alt Text

Alt Text

So I indexed out the 7K (7776) lines from the middle of the file that I actually care about. Remembering that each of these lines contain both a five-digit number and the corresponding word, I used the split method to break them apart, and then build the list containing just the words.

Then I used the "secrets.choice" function within another list comprehension to build a list with the desired number of random words.

And finally, I used the join method to combine the random words into a single string with spaces between them:

Alt Text

Extra Project Ideas:

projects of Python installation and packaging

PyPA Projects

bandersnatch

Issues | GitHub | PyPI

bandersnatch is a PyPI mirroring client designed to efficiently create a complete mirror of the contents of PyPI. Organizations thus save bandwidth and latency on package downloads (especially in the context of automated tests) and to prevent heavily loading PyPI’s Content Delivery Network (CDN).

build

Docs | Issues | GitHub | PyPI

build is a PEP 517 compatible Python package builder. It provides a CLI to build packages, as well as a Python API.

cibuildwheel

Docs | Issues | GitHub | PyPI | Discussions | Discord #cibuildwheel

cibuildwheel is a Python package that builds wheels for all common platforms and Python versions on most CI systems. Also see multibuild.

distlib

Docs | Issues | Bitbucket | PyPI

distlib is a library which implements low-level functions that relate to packaging and distribution of Python software. distlib implements several relevant PEPs (Python Enhancement Proposal standards) and is useful for developers of third-party packaging tools to make and upload binary and source distributions, achieve interoperability, resolve dependencies, manage package resources, and do other similar functions.

Unlike the stricter packaging project (below), which specifically implements modern Python packaging interoperability standards, distlib also attempts to provide reasonable fallback behaviours when asked to handle legacy packages and metadata that predate the modern interoperability standards and fall into the subset of packages that are incompatible with those standards.

packaging

Docs | Issues | GitHub | PyPI

Core utilities for Python packaging used by pip and setuptools.

The core utilities in the packaging library handle version handling, specifiers, markers, requirements, tags, and similar attributes and tasks for Python packages. Most Python users rely on this library without needing to explicitly call it; developers of the other Python packaging, distribution, and installation tools listed here often use its functionality to parse, discover, and otherwise handle dependency attributes.

This project specifically focuses on implementing the modern Python packaging interoperability standards defined at PyPA specifications, and will report errors for sufficiently old legacy packages that are incompatible with those standards. In contrast, the distlib project is a more permissive library that attempts to provide a plausible reading of ambiguous metadata in cases where packaging will instead report on error.

pip

Docs | Issues | GitHub | PyPI

The most popular tool for installing Python packages, and the one included with modern versions of Python.

It provides the essential core features for finding, downloading, and installing packages from PyPI and other Python package indexes, and can be incorporated into a wide range of development workflows via its command-line interface (CLI).

Pipenv

Docs | Source | Issues | PyPI

Pipenv is a project that aims to bring the best of all packaging worlds to the Python world. It harnesses Pipfile, pip, and virtualenv into one single toolchain. It features very pretty terminal colors.

Pipenv aims to help users manage environments, dependencies, and imported packages on the command line. It also works well on Windows (which other tools often underserve), makes and checkes file hashes, to ensure compliance with hash-locked dependency specifiers, and eases uninstallation of packages and dependencies. It is used by Python users and system administrators, but has been less maintained since late 2018.

Pipfile

Source

Pipfile and its sister Pipfile.lock are a higher-level application-centric alternative to pip’s lower-level requirements.txt file.

pipx

Docs | GitHub | PyPI

pipx is a tool to install and run Python command-line applications without causing dependency conflicts with other packages installed on the system.

Python Packaging User Guide

Docs | Issues | GitHub

This guide!

readme_renderer

GitHub and docs | PyPI

readme_renderer is a library that package developers use to render their user documentation (README) files into HTML from markup languages such as Markdown or reStructuredText. Developers call it on its own or via twine, as part of their release management process, to check that their package descriptions will properly display on PyPI.

setuptools

Docs | Issues | GitHub | PyPI

setuptools (which includes easy_install) is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python distributions, especially ones that have dependencies on other packages.

distribute was a fork of setuptools that was merged back into setuptools (in v0.7), thereby making setuptools the primary choice for Python packaging.

trove-classifiers

Issues | GitHub | PyPI

trove-classifiers is the canonical source for classifiers on PyPI, which project maintainers use to systematically describe their projects so that users can better find projects that match their needs on the PyPI.

The trove-classifiers package contains a list of valid classifiers and deprecated classifiers (which are paired with the classifiers that replace them). Use this package to validate classifiers used in packages intended for uploading to PyPI. As this list of classifiers is published as code, you can install and import it, giving you a more convenient workflow compared to referring to the list published on PyPI. The issue tracker for the project hosts discussions on proposed classifiers and requests for new classifiers.

twine

Docs | Issues | GitHub | PyPI

Twine is the primary tool developers use to upload packages to the Python Package Index or other Python package indexes. It is a command-line program that passes program files and metadata to a web API. Developers use it because it’s the official PyPI upload tool, it’s fast and secure, it’s maintained, and it reliably works.

virtualenv

Docs | Issues | GitHub | PyPI

virtualenv is a tool which uses the command-line path environment variable to create isolated Python Virtual Environments, much as venv does. virtualenv provides additional functionality, compared to venv, by supporting Python 2.7 and by providing convenient features for configuring, maintaining, duplicating, and troubleshooting the virtual environments. For more information, see the section on Creating Virtual Environments.

Warehouse

Docs | Issues | GitHub

The current codebase powering the Python Package Index (PyPI). It is hosted at pypi.org. The default source for pip downloads.

wheel

Docs | Issues | GitHub | PyPI

Primarily, the wheel project offers the bdist_wheel setuptools extension for creating wheel distributions. Additionally, it offers its own command line utility for creating and installing wheels.

See also auditwheel, a tool that package developers use to check and fix Python packages they are making in the binary wheel format. It provides functionality to discover dependencies, check metadata for compliance, and repair the wheel and metadata to properly link and include external shared libraries in a package.

Non-PyPA Projects

buildout

Docs | Issues | PyPI | GitHub

Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.

conda

Docs

conda is the package management tool for Anaconda Python installations. Anaconda Python is a distribution from Anaconda, Inc specifically aimed at the scientific community, and in particular on Windows where the installation of binary extensions is often difficult.

Conda is a completely separate tool from pip, virtualenv and wheel, but provides many of their combined features in terms of package management, virtual environment management and deployment of binary extensions.

Conda does not install packages from PyPI and can install only from the official Anaconda repositories, or anaconda.org (a place for user-contributed conda packages), or a local (e.g. intranet) package server. However, note that pip can be installed into, and work side-by-side with conda for managing distributions from PyPI. Also, conda skeleton is a tool to make Python packages installable by conda by first fetching them from PyPI and modifying their metadata.

devpi

Docs | Issues | PyPI

devpi features a powerful PyPI-compatible server and PyPI proxy cache with a complementary command line tool to drive packaging, testing and release activities with Python. devpi also provides a browsable and searchable web interface.

flit

Docs | Issues | PyPI

Flit provides a simple way to upload pure Python packages and modules to PyPI. It focuses on making the easy things easy for packaging. Flit can generate a configuration file to quickly set up a simple project, build source distributions and wheels, and upload them to PyPI.

Flit uses pyproject.toml to configure a project. Flit does not rely on tools such as setuptools to build distributions, or twine to upload them to PyPI. Flit requires Python 3, but you can use it to distribute modules for Python 2, so long as they can be imported on Python 3.

enscons

Source | Issues | PyPI

Enscons is a Python packaging tool based on SCons. It builds pip-compatible source distributions and wheels without using distutils or setuptools, including distributions with C extensions. Enscons has a different architecture and philosophy than distutils. Rather than adding build features to a Python packaging system, enscons adds Python packaging to a general purpose build system. Enscons helps you to build sdists that can be automatically built by pip, and wheels that are independent of enscons.

Hashdist

Docs | GitHub

Hashdist is a library for building non-root software distributions. Hashdist is trying to be “the Debian of choice for cases where Debian technology doesn’t work”. The best way for Pythonistas to think about Hashdist may be a more powerful hybrid of virtualenv and buildout. It is aimed at solving the problem of installing scientific software, and making package distribution stateless, cached, and branchable. It is used by some researchers but has been lacking in maintenance since 2016.

hatch

GitHub and Docs | PyPI

Hatch is a unified command-line tool meant to conveniently manage dependencies and environment isolation for Python developers. Python package developers use Hatch to configure, version, specify dependencies for, and publish packages to PyPI. Under the hood, it uses twine to upload packages to PyPI, and pip to download and install packages.

multibuild

GitHub

Multibuild is a set of CI scripts for building and testing Python wheels for Linux, macOS, and (less flexibly) Windows. Also see cibuildwheel.

pex

Docs | GitHub | PyPI

pex is both a library and tool for generating .pex (Python EXecutable) files, standalone Python environments in the spirit of virtualenv. .pex files are just carefully constructed zip files with a #!/usr/bin/env python and special __main__.py, and are designed to make deployment of Python applications as simple as cp.

pip-tools

GitHub and Docs | PyPI

pip-tools is a suite of tools meant for Python system administrators and release managers who particularly want to keep their builds deterministic yet stay up to date with new versions of their dependencies. Users can specify particular release of their dependencies via hash, conveniently make a properly formatted list of requirements from information in other parts of their program, update all dependencies (a feature pip currently does not provide), and create layers of constraints for the program to obey.

piwheels

Website | Docs | GitHub

piwheels is a website, and software underpinning it, that fetches source code distribution packages from PyPI and compiles them into binary wheels that are optimized for installation onto Raspberry Pi computers. Raspberry Pi OS pre-configures pip to use piwheels.org as an additional index to PyPI.

poetry

Docs | GitHub | PyPI

poetry is a command-line tool to handle dependency installation and isolation as well as building and packaging of Python packages. It uses pyproject.toml and, instead of depending on the resolver functionality within pip, provides its own dependency resolver. It attempts to speed users’ experience of installation and dependency resolution by locally caching metadata about dependencies.

pypiserver

Docs | GitHub | PyPI

pypiserver is a minimalist application that serves as a private Python package index within organizations, implementing a simple API and browser interface. You can upload private packages using standard upload tools, and users can download and install them with pip, without publishing them publicly. Organizations who use pypiserver usually download packages both from pypiserver and from PyPI.

scikit-build

Docs | GitHub | PyPI

Scikit-build is an improved build system generator for CPython C/C++/Fortran/Cython extensions that integrates with setuptools, wheel and pip. It internally uses cmake (available on PyPI) to provide better support for additional compilers, build systems, cross compilation, and locating dependencies and their associated build requirements. To speed up and parallelize the build of large projects, the user can install ninja (also available on PyPI).

shiv

Docs | GitHub | PyPI

shiv is a command line utility for building fully self contained Python zipapps as outlined in PEP 441, but with all their dependencies included. Its primary goal is making distributing Python applications and command line tools fast & easy.

Spack

Docs | GitHub | Paper | Slides

A flexible package manager designed to support multiple versions, configurations, platforms, and compilers. Spack is like Homebrew, but packages are written in Python and parameterized to allow easy swapping of compilers, library versions, build options, etc. Arbitrarily many versions of packages can coexist on the same system. Spack was designed for rapidly building high performance scientific applications on clusters and supercomputers.

Spack is not in PyPI (yet), but it requires no installation and can be used immediately after cloning from GitHub.

zest.releaser

Docs | GitHub | PyPI

zest.releaser is a Python package release tool providing an abstraction layer on top of twine. Python developers use zest.releaser to automate incrementing package version numbers, updating changelogs, tagging releases in source control, and uploading new packages to PyPI.

Standard Library Projects

ensurepip

Docs | Issues

A package in the Python Standard Library that provides support for bootstrapping pip into an existing Python installation or virtual environment. In most cases, end users won’t use this module, but rather it will be used during the build of the Python distribution.

distutils

Docs | Issues

The original Python packaging system, added to the standard library in Python 2.0.

Due to the challenges of maintaining a packaging system where feature updates are tightly coupled to language runtime updates, direct usage of distutils is now actively discouraged, with setuptools being the preferred replacement. setuptools not only provides features that plain distutils doesn’t offer (such as dependency declarations and entry point declarations), it also provides a consistent build interface and feature set across all supported Python versions.

venv

Docs | Issues

A package in the Python Standard Library (starting with Python 3.3) for creating Virtual Environments. For more information, see the section on Creating Virtual Environments.